#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "kill.h"
#include "exit_status.h"

#define strdup _strdup

/* Up to 128 songs, for now */
static char *songs[128];
static int should_shuffle = 0;
static int song_count = 0;
static char read_buf[1024];

static void callback_playlist() {
	for (size_t i = 0; i < 128; ++i) {
		if (songs[i]) free(songs[i]);
	}
}

void playlist_init() {
	for (size_t i = 0; i < 128; ++i) songs[i] = NULL;
	kill_push(callback_playlist);
}

void playlist_load(const char *path) {
	FILE *f = fopen(path, "r");
	if (!f) {
		printf("Could not open playlist '%s'\n", path);
		kill(EX_ERR_BAD_PLAYLIST);
	}

	int write = 0;
	int song_write = 0;
	for (;;) {
		int c = fgetc(f);
		if (c == EOF) break;
		if (c == '\n') {
			if (read_buf[0] == '+') {
				read_buf[write] = '\0';
				if (!strcmp(read_buf, "+shuffle")) {
					should_shuffle = 1;
				}
			}
			else {
				read_buf[write] = '\0';
				songs[song_write++] = strdup(read_buf);
				if (song_write >= 128) break;
			}
			write = 0;
		}
		else read_buf[write++] = (char)c;

		if (write >= 1024) {
			break;
		}
	}

	fclose(f);

	song_count = song_write;
	if (song_count == 0) {
		printf("Playlist '%s' contains no songs!", path);
		kill(EX_ERR_NO_SONGS);
	}
}

static const char *next_normal() {
	static int index = 0;
	char *result = songs[index];
	index = (index + 1) % song_count;
	return result;
}

static const char *next_shuffle() {
	static int has_played[128] = { 0 };
	
	size_t choices[128];
	size_t choice_count = 0;

	for (size_t i = 0; i < song_count; ++i) {
		if (!has_played[i]) {
			choices[choice_count++] = i;
		}
	}

	if (choice_count == 0) {
		for (size_t i = 0; i < song_count; ++i) {
			has_played[i] = 0;
			choices[i] = i;
		}
		choice_count = song_count;
	}

	size_t index = ((rand() / (float)RAND_MAX) * (choice_count - 1));
	char *result = songs[choices[index]];
	has_played[choices[index]] = 1;
	return result;
}

const char *playlist_next() {
	if (should_shuffle) return next_shuffle();
	return next_normal();
}